async: a vectored write the caller can await - #24
Merged
Conversation
The vectored write is fire-and-forget in both of its modes: the completion sends no notification and the release callback carries no status. A caller that needs the outcome therefore has to use the single-buffer write, which does not take the buffer over — so it must free it itself, and the only moment it can is when its own wait ends. Those are different moments once the waiting coroutine is cancelled: the wait is over and the write is not. ZEND_ASYNC_IO_WRITEV_AWAIT says the caller waits. Ownership stays the mode's; the completion keeps the request alive and notifies io->event with the request as the result and no exception, so a caller matching by request pointer wakes and no sibling awaiter on the same handle does. Header only: the flag word already existed, so no signature changes and the existing values keep their meaning.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Needed by true-async/php-async and true-async/server: the HTTP/1 server frees a write buffer that libuv still points at, because the only write that reports its status is also the only one that leaves the buffer with the caller.
Both vectored modes are fire-and-forget —
io_pipe_writev_cbsends no NOTIFY and its release callback takes no status — so a caller that needs the outcome must use the single-buffer write, keep the buffer, and free it when its own wait ends. Once the waiting coroutine is cancelled that moment arrives before the write completes, and the freed bytes stay in libuv's queue.ZEND_ASYNC_IO_WRITEV_AWAITmarks a vectored write as awaited. Buffer ownership is unchanged — it stays whatever the mode says — and only the completion differs: the request stays alive andio->eventis notified with the request as the result and no exception, so a caller matching by request pointer wakes while sibling awaiters on the same handle do not.Header only. The
flagsword already existed, so nothing changes signature andZEND_ASYNC_IO_WRITEV_ZSTR/_IOVkeep their values;_MODE_MASKnames the bit they occupy. The reactor side is true-async/php-async, the consumer is true-async/server.